import { Injectable, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from './entity/user.entity';
import { UpdateUserDto, UpdatePasswordDto, SwitchEmailDto } from './dto/user.dto';
import { RedisService } from '../redis/redis.service';
import * as bcrypt from 'bcrypt';

@Injectable()
export class UserService {
  constructor(
    @InjectRepository(User)
    private readonly userRepository: Repository<User>,
    private readonly redisService: RedisService,
  ) { }

  /**
   * ? 获取用户信息
   * @param user_id 用户ID
   * @returns 用户实体
   */
  async getUserInfo(user_id: number) {
    try {
      const user = await this.userRepository.findOne({
        where: {
          id: user_id,
        },
      });
      if (!user) {
        throw new NotFoundException('用户不存在');
      }
      return {
        code: 200,
        msg: '获取用户成功',
        data: user,
      };
    } catch (error) {
      throw new NotFoundException(error.message);
    }
  }

  /**
   * ? 更新用户信息
   * @param user_id 用户ID
   * @param updateUserDto 更新用户 dto
   */
  async updateUserInfo(user_id: number, updateUserDto: UpdateUserDto) {
    try {
      const user = await this.getUserInfo(user_id);
      if (user.code !== 200) {
        throw new NotFoundException(user.msg);
      }
      console.log(user);
      const { user_id: userId, ...reset } = updateUserDto
      const result = await this.userRepository.update(userId, reset);
      if (result.affected === 0) {
        throw new Error('更新用户时出现异常');
      }
      // 受影响的行数为 1 表示更新成功
      if (result.affected === 1) {
        return {
          code: 200,
          msg: '更新用户成功',
        };
      } else {// 受影响的行数大于 1 表示更新了多个用户，这是一个异常情况
        throw new Error('更新用户时出现异常');
      }
    } catch (error) {
      throw new NotFoundException(error.message);
    }
  }

  /**
   * ? 删除用户
   * @param user_id 用户ID
   * @returns 删除结果
   */
  async deleteUser(user_id: number) {
    try {
      const user = await this.getUserInfo(user_id);
      if (user.code !== 200) {
        throw new NotFoundException(user.msg);
      }
      const result = await this.userRepository.update(user_id, {
        status: '0',
      });
      // result.affected 表示受影响的行数
      // 受影响的行数为 0 表示删除失败
      if (result.affected === 0) {
        throw new Error('删除用户时出现异常');
      }
      // 受影响的行数为 1 表示删除成功
      if (result.affected === 1) {
        return {
          code: 200,
          msg: '删除用户成功',
        };
      } else {// 受影响的行数大于 1 表示删除了多个用户，这是一个异常情况
        throw new Error('删除用户时出现异常');
      }
    } catch (error) {
      throw new NotFoundException(error.message);
    }
  }

  /**
   * ? 更新用户密码
   * @param user_id 用户ID
   * @param updatePasswordDto 更新密码 dto
   */
  async updateUserPassword(user_id: number, updatePasswordDto: UpdatePasswordDto) {
    try {
      const user = await this.getUserInfo(user_id);
      if (user.code !== 200) {
        throw new NotFoundException('用户不存在');
      }

      // 先验证旧密码是否与加密后的密码匹配
      const isPasswordValid = await bcrypt.compare(updatePasswordDto.oldPassword, user.data.password);
      if (!isPasswordValid) {
        throw new NotFoundException('旧密码错误');
      }

      // 对新密码进行加密并更新用户密码
      const newPasswordHash = await bcrypt.hash(updatePasswordDto.newPassword, 10);
      const result = await this.userRepository.update(user_id, {
        password: newPasswordHash,
      });

      // 受影响的行数为 0 表示更新失败
      if (result.affected === 0) {
        throw new Error('更新用户密码时出现异常');
      }
      // 受影响的行数为 1 表示更新成功
      if (result.affected === 1) {
        return {
          code: 200,
          msg: '更新用户密码成功',
        };
      } else {// 受影响的行数大于 1 表示更新了多个用户，这是一个异常情况
        throw new Error('更新用户密码时出现异常');
      }
    } catch (error) {
      throw new NotFoundException(error.message);
    }
  }

  /**
   * ? 切换用户邮箱
   * @param user_id 用户ID
   * @param switchEmailDto 切换邮箱 dto
   */
  async switchUserEmail(user_id: number, switchEmailDto: SwitchEmailDto) {
    try {
      const user = await this.getUserInfo(user_id);
      if (user.code !== 200) {
        throw new NotFoundException('用户不存在');
      }

      const REDIS_KEY = `switch_email:${switchEmailDto.email}`;
      // 从 Redis 中获取验证码
      const storedCode = await this.redisService.getCode(REDIS_KEY);
      if (!storedCode) {
        throw new NotFoundException('验证码过期或不存在');
      }
      // 验证验证码是否匹配
      if (storedCode !== switchEmailDto.code) {
        throw new NotFoundException('验证码错误');
      }

      // 更新用户邮箱
      const result = await this.userRepository.update(user_id, {
        email: switchEmailDto.email,
      });
      // 受影响的行数为 0 表示更新失败
      if (result.affected === 0) {
        throw new Error('更新用户邮箱时出现异常');
      }
      // 受影响的行数为 1 表示更新成功
      if (result.affected === 1) {
        return {
          code: 200,
          msg: '更新用户邮箱成功',
        };
      } else {// 受影响的行数大于 1 表示更新了多个用户，这是一个异常情况
        throw new Error('更新用户邮箱时出现异常');
      }
    } catch (error) {
      throw new NotFoundException(error.message);
    }
  }
}